package com.soloyogame.anitoys.lists.web.controller.interceptor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.soloyogame.anitoys.db.commond.Account;
import com.soloyogame.anitoys.db.commond.Business;
import com.soloyogame.anitoys.db.commond.CartInfo;
import com.soloyogame.anitoys.db.commond.Catalog;
import com.soloyogame.anitoys.db.commond.Help;
import com.soloyogame.anitoys.db.commond.News;
import com.soloyogame.anitoys.db.commond.Product;
import com.soloyogame.anitoys.db.commond.SystemSetting;
import com.soloyogame.anitoys.lists.web.util.LoginUserHolder;
import com.soloyogame.anitoys.service.BusinessService;
import com.soloyogame.anitoys.service.CatalogService;
import com.soloyogame.anitoys.service.HelpService;
import com.soloyogame.anitoys.service.NewsService;
import com.soloyogame.anitoys.service.ProductService;
import com.soloyogame.anitoys.service.SystemSettingService;
import com.soloyogame.anitoys.util.cache.RedisCacheProvider;
import com.soloyogame.anitoys.util.constants.ManageContainer;
import com.soloyogame.anitoys.util.front.FrontContainer;

/**
 * @author 索罗游
 */
public class AnitoysInterceptor implements HandlerInterceptor 
{
        private static final Logger LOGGER = LoggerFactory.getLogger(AnitoysInterceptor.class);

        @Autowired
        private BusinessService businessService;
        @Autowired
        private CatalogService catalogService;
        @Autowired
        private NewsService newsService;
        @Autowired
        private HelpService helpService;
        @Autowired
        private SystemSetting systemSetting;
        @Autowired
        private SystemSettingService systemSettingService;
        @Autowired
        private RedisCacheProvider redisCacheProvider;
        @Autowired
    	private ProductService productService;//商品服务

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 
        {

        	 // 加载 商家列表
            List<Business> businessList = loadBusinessList();
            request.setAttribute("businessList", businessList);
            
            // 加载文章目录
            List<Catalog> newCatalogs = loadCatalogNews();
            request.setAttribute("newsCatalogs", newCatalogs);

            // 加载帮助支持
            List<Help> helpList = loadHelpList();
            request.setAttribute("helpList", helpList);
           
            //加载系统设置
            systemSetting=loadSystemSetting();
            
            //加载购物车信息
            CartInfo cartInfo = getMyCart();
            List<Product> productList = new ArrayList<Product>();
            if (cartInfo != null) 
            {
                productList = cartInfo.getProductList();
            } 
            else 
            {
                cartInfo = new CartInfo();
            }
            request.setAttribute("cartInfo", cartInfo);
            request.setAttribute("productList", productList);
            
        	//商品目录
    		List<Catalog> catalogs = loadCatalogs(true);
    		request.setAttribute("catalogs", catalogs);
            return true;
        }

        /**
         *
         * postHandle(controller处理过后 会进入此方法)
         *
         * @Title: postHandle
         * @Description:
         * @param @param request
         * @param @param response
         * @param @param handler
         * @param @param modelAndView
         * @param @throws Exception
         * @throws
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {


        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        }
        
        /**
         * 加载系统配置信息
         */
        public SystemSetting loadSystemSetting() 
        {
        	 Serializable serializable;
             try 
             {
                 serializable =  redisCacheProvider.get(ManageContainer.CACHE_SYSTEM_SETTING);
             } 
             catch (Exception e) 
             {
                 serializable = null;
             }
             String nullValue = "null";
             if (serializable == null || serializable.toString().equals(nullValue)) 
             {
            	 systemSetting = systemSettingService.selectOne(new SystemSetting());
             }
             else
             {
            	 systemSetting = JSON.parseObject(serializable.toString(), SystemSetting.class);
             }
             redisCacheProvider.put(ManageContainer.CACHE_SYSTEM_SETTING, JSON.toJSONString(systemSetting));
             return systemSetting;
        }

        /**
         * 加载文章列表
         * @return
         */
        private   List<Catalog> loadCatalogNews() 
        {
            List<Catalog> newCatalogs = new ArrayList<Catalog>();
            Serializable serializable;
            try 
            {
                serializable =  redisCacheProvider.get(ManageContainer.CACHE_NEWSCATALOGS);
            } 
            catch (Exception e) 
            {
                serializable = null;
            }
            String nullValue = "null";
            if (serializable == null || serializable.toString().equals(nullValue)) 
            {
                // 查询 文章目录
                Catalog c = new Catalog();
                c.setType("a");
                c.setPid("0");
                c.setShowInNav("y");
                newCatalogs = catalogService.selectList(c);
                if (newCatalogs != null && newCatalogs.size() > 0) 
                {
                    for (int i = 0; i < newCatalogs.size(); i++) 
                    {
                        Catalog catalog = newCatalogs.get(i);
                        //加载此目录下的所有文章列表
                        News news = new News();
                        news.setCatalogID(catalog.getId());
                        news.setStatus("y");
                        List<News> newsList = newsService.selectPlatList(news);
                        catalog.setNews(newsList);
                    }
                }
            } 
            else 
            {
                newCatalogs =  JSON.parseArray(serializable.toString(), Catalog.class);
            }
            redisCacheProvider.put(ManageContainer.CACHE_NEWSCATALOGS, JSON.toJSONString(newCatalogs));
            return newCatalogs;
        }

        /**
         * 加载商家列表
         * @return List<Business>
         */
        private   List<Business> loadBusinessList() 
        {

            Business business = new Business();
            List<Business> businessList = new ArrayList<Business>();
            Serializable serializable;
            try {
                serializable =  redisCacheProvider.get(ManageContainer.CACHE_BUSINESSLIST);
            } catch (Exception e) {
                serializable = null;
            }
            String nullValue = "null";
            if (serializable == null || serializable.toString().equals(nullValue)) {
                // 查询 商家列表
                businessList = businessService.selectList(business);
            } else {
                businessList =  JSON.parseArray(serializable.toString(), Business.class);
            }
            redisCacheProvider.put(ManageContainer.CACHE_BUSINESSLIST, JSON.toJSONString(businessList));

            return businessList;
        }

    /**
     * 帮助支持列表
     * @return List<Help>
     */
    private   List<Help> loadHelpList() {
        List<Help> helpList = new ArrayList<Help>();
        Serializable serializable;
        try {
            serializable =  redisCacheProvider.get(ManageContainer.CACHE_HELPLIST);
        } catch (Exception e) {
            serializable = null;
        }
        String nullValue = "null";
        if (serializable == null || serializable.toString().equals(nullValue)) {
            //	帮助支持列表
            Help help = new Help();
            help.setStatus("y");
            helpList = helpService.selectList(help);
        } else {
            helpList =  JSON.parseArray(serializable.toString(), Help.class);
        }
        redisCacheProvider.put(ManageContainer.CACHE_HELPLIST, JSON.toJSONString(helpList));

        return helpList;
    }
    
    /**
     * 加载购物车
     * @return
     */
    protected CartInfo getMyCart() 
    {
        Account account = LoginUserHolder.getLoginAccount();    //得到登录用户的信息
        CartInfo cartInfo = null;
        if (account == null) 
        {
            cartInfo = (CartInfo) redisCacheProvider.get("myCart");
        }
        else 
        {
            cartInfo = (CartInfo) redisCacheProvider.get("user_" + account.getId() + "Cart");
        }
        return cartInfo;
    }
    
    /**
	 * 加载目录列表,树形结构
	 * @param loadProduct 是否加载商品数据。true：加载，false:不加载
	 * @throws Exception
	 */
	public List<Catalog> loadCatalogs(boolean loadProduct) throws Exception 
	{
		 Serializable serializable;
    	 List<Catalog> catalogs = new ArrayList<Catalog>();
         try 
         {
             serializable =  redisCacheProvider.get(ManageContainer.CACHE_CATALOGS);
         } 
         catch (Exception e) 
         {
             serializable = null;
         }
         String nullValue = "null";
         if (serializable == null || serializable.toString().equals(nullValue)) 
         {
        	 catalogs = loadCatalogs2("p");
         }
         else
         {
        	 catalogs =  JSON.parseArray(serializable.toString(), Catalog.class);
         }
         redisCacheProvider.put(ManageContainer.CACHE_CATALOGS, JSON.toJSONString(catalogs));
        Map<String, Catalog> catalogsMap = Maps.newHashMap();
        Map<String, Catalog> catalogsCodeMap = Maps.newHashMap();
		putToMap(catalogs, loadProduct, catalogsMap, catalogsCodeMap);
		return catalogs;
	}
	
	/**
	 * 原来递归的方式修改为非递归方式。
	 * 非递归方法查询商品/文章目录结构，并且自动排序。
	 * @param type
	 */
	private List<Catalog> loadCatalogs2(String type)
	{
        List<Catalog> catalogs = Lists.newLinkedList();
		Catalog cc = new Catalog();
		cc.setType(type);
		List<Catalog> catalogsList = catalogService.selectList(cc);
		if(catalogsList!=null)
		{

			Map<String, Catalog> map = new HashMap<String, Catalog>();
			for(Iterator<Catalog> it = catalogsList.iterator();it.hasNext();)
			{
				Catalog item = it.next();

				if(StringUtils.isNotBlank(item.getPid()) && item.getPid().equals("0"))
				{
					//是否在导航栏显示中文化
					if(item.getShowInNav().equals(Catalog.catalog_showInNav_y))
					{
						item.setShowInNavStr("是");
					}
					map.put(item.getId(), item);
					it.remove();
				}
			}

			for(Iterator<Catalog> it = catalogsList.iterator();it.hasNext();)
			{
				Catalog item = it.next();
				if(StringUtils.isNotBlank(item.getPid()))
				{
					Catalog rootItem = map.get(item.getPid());
					if(rootItem!=null)
					{
						if(rootItem.getChildren()==null)
						{
							rootItem.setChildren(new LinkedList<Catalog>());
						}
						rootItem.getChildren().add(item);
					}
					it.remove();
				}
			}

			for(Iterator<Entry<String, Catalog>> it = map.entrySet().iterator();it.hasNext();)
			{
				catalogs.add(it.next().getValue());
			}

			//对主类别和子类别进行排序
			Collections.sort(catalogs, new Comparator<Catalog>() 
			{
				public int compare(Catalog o1, Catalog o2) 
				{
					if (o1.getOrder1() > o2.getOrder1()) 
					{
						return 1;
					} 
					else if (o1.getOrder1() < o2.getOrder1()) 
					{
						return -1;
					}
					return 0;
				}
			});

			for(int i=0;i<catalogs.size();i++)
			{
				if(catalogs.get(i).getChildren()==null)
				{
					continue;
				}
				Collections.sort(catalogs.get(i).getChildren(), new Comparator<Catalog>() {
					public int compare(Catalog o1, Catalog o2) 
					{
						if (o1.getOrder1() > o2.getOrder1()) 
						{
							return 1;
						} 
						else if (o1.getOrder1() < o2.getOrder1()) 
						{
							return -1;
						}
						return 0;
					}
				});
			}
		}
        return catalogs;
	}
	
	/**
	 * 将商品目录结构转化为map的形式。
	 * @param catalogs
	 * @throws Exception
	 */
	public void putToMap(List<Catalog> catalogs,boolean loadProduct, Map<String, Catalog> catalogsMap, Map<String, Catalog> catalogsCodeMap) throws Exception
	{
		if(catalogs==null || catalogs.size()==0)
		{
			return;
		}
		for(int i=0;i<catalogs.size();i++)
		{
			Catalog item = catalogs.get(i);
			if(loadProduct)
			{
				//超级菜单里面的推荐商品
				loadsuperMenuProducts(item);
				//加载每个目录下的热门推荐商品列表
				loadHotProductByCatalog(item);
			}
			catalogsMap.put(item.getId(),item);
			if(catalogsCodeMap.get(item.getCode())!=null)
			{
				throw new Exception("错误：商品类别code重复!");
			}
			catalogsCodeMap.put(item.getCode(),item);
			if(item.getChildren()!=null && item.getChildren().size()>0)
			{
				//递归调用
				putToMap(item.getChildren(),loadProduct, catalogsMap, catalogsCodeMap);
			}
		}
	}
	
	/**
	 * 加载超级菜单的位置显示的热门推荐商品列表
	 * @param item
	 */
	private void loadsuperMenuProducts(Catalog item)
	{
		if(!item.getPid().equals("0"))
		{
			//子目录则不加载任何数据
			return;
		}

		if(item.getChildren()==null || item.getChildren().size()==0)
		{
			return;
		}
		List<String> ids = new LinkedList<String>();
		for(int j=0;j<item.getChildren().size();j++)
		{
			ids.add(item.getChildren().get(j).getId());
		}

		Product product = new Product();
		product.setTop(3);         //显示的最大个数
		product.setProductIds(ids);//目录集合
		List<Product> superMenuProducts = productService.loadHotProductShowInSuperMenu(product);
		if(superMenuProducts!=null && superMenuProducts.size()>0){
			item.setSuperMenuProducts(superMenuProducts);
		}
	}

	/**
	 * 加载每个目录下的热门推荐商品列表（包括子目录）
	 * @param item
	 */
	private void loadHotProductByCatalog(Catalog item)
	{
		if(item.getPid().equals("0") && (item.getChildren()==null || item.getChildren().size()==0))
		{
			return;
		}
		Product p = new Product();
		p.setTop(FrontContainer.default_page_left_product_size);

		if(item.getPid().equals("0"))
		{
			List<Integer> ids = new LinkedList<Integer>();
			for(int j=0;j<item.getChildren().size();j++)
			{
				ids.add(Integer.valueOf(item.getChildren().get(j).getId()));
			}
			p.setQueryCatalogIDs(ids);
		}
		else
		{
			p.setCatalogID(item.getId());
		}
		List<Product> hotProducts = productService.selectPageLeftHotProducts(p);
		if(hotProducts!=null && hotProducts.size()>0)
		{
			item.setHotProducts(hotProducts);
		}
	}

}
